import pickle
from typing import Annotated

from fastapi import APIRouter, Header, Depends

from app_v2.AsyncDataBase import get_async_db_cursor
from app_v2.bili_api.api import ApiSession
from app_v2.dependencys import get_redis
from app_v2.model import fmt, TrendingPageParams

up = APIRouter(prefix="/up", tags=["up"])


@up.get("/basic_info")
async def up_basic_info(mid: str, token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("up:basic_info:{}".format(mid))
        if data:
            return {"code": 200, "data": pickle.loads(data)}

    async with ApiSession(token) as session:
        info = await session.up(mid).info()

    await redis.setex("up:basic_info:{}".format(mid), 3600, pickle.dumps(info.to_dict()))
    return info.to_dict()


@up.get("/word_cloud")
async def word_cloud(mid: str, token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("up:word_cloud:{}".format(mid))
        if data:
            return {"code": 200, "data": pickle.loads(data)}

    async with ApiSession(token) as session:
        data = await session.up(mid).up_word_cloud()

    res = [{"text": word, "size": count} for word, count in data[:20]]
    await redis.setex("up:word_cloud:{}".format(mid), 3600, pickle.dumps(res))
    return {"code": 200, "data": res}


@up.get("/pub_video")
async def up_pub_video(mid: str, token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("up:pub_video:{}".format(mid))
        if data:
            return {"code": 200, "data": pickle.loads(data)}
    async with ApiSession(token) as session:
        data = await session.up(mid).pub_video_bvids()
    await redis.setex("up:pub_video:{}".format(mid), 3600, pickle.dumps(data))
    return {"code": 200, "data": data}


@up.get("/dynamic")
async def dynamic(mid: str, token: Annotated[str | None, Header()], update=False, redis=Depends(get_redis)):
    if not update:
        data = await redis.get("up:dynamic:{}".format(mid))
        if data:
            return {"code": 200, "data": pickle.loads(data)}
    async with ApiSession(token) as session:
        data = await session.up(mid).dynamic_info()
    await redis.setex("up:dynamic:{}".format(mid), 3600, pickle.dumps(data))
    return {
        "code": 200,
        "data": data
    }


@up.get("/change/follower")
async def up_followers_change(mid: str, params: TrendingPageParams = Depends(), cursor=Depends(get_async_db_cursor)):
    await cursor.execute(
        f"""
    SELECT MAX(follower) as follower, DATE_FORMAT(date, %s) as date
    FROM user_info
    WHERE mid = %s
    GROUP BY DATE_FORMAT(date, %s)
    ORDER BY DATE_FORMAT(date, %s) DESC
    LIMIT %s
    OFFSET %s
    """,
        [fmt[params.mode.value], mid, fmt[params.mode.value], fmt[params.mode.value], params.ps, params.ps * params.pn])
    res = await cursor.fetchall()
    return {
        "code": 200,
        "data": res,
    }
